package com.example.dormmanage.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.dormmanage.dao.IAdminBuildingDao;
import com.example.dormmanage.dao.IAdminDao;
import com.example.dormmanage.dao.IAreaDao;
import com.example.dormmanage.dao.IBuildingDao;
import com.example.dormmanage.entity.*;
import com.example.dormmanage.service.IAdminService;
import com.example.dormmanage.util.CustomerException;
import com.example.dormmanage.util.JwtUtil;
import com.example.dormmanage.view.ResultView;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class AdminService extends ServiceImpl<IAdminDao, Admin> implements IAdminService {

    //管理员登录
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private IAdminBuildingDao adminBuildingDao;

    @Autowired
    private IAreaDao areaDao;

    @Autowired
    private IBuildingDao buildingDao;

    //管理员登录
    public ResultView adminLogin(Admin admin) {
        //AuthenticationManager authenticate进行用户认证
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(admin.getUserName(), admin.getPassword());
        Authentication authentication = authenticationManager.authenticate(authenticationToken);
        //如果认证没通过,给出对应的提示
        if (authentication == null) {
            throw new CustomerException("用户名或密码错误");
        }
        LoginUser adminLoginUser = (LoginUser) authentication.getPrincipal();
        Map<String, String> map = new HashMap<>();
        //判断用户是否是第一次登录
        if (adminLoginUser.getAdmin().getLastLoginTime() == null && !adminLoginUser.getAdmin().getUserName().equals("admin")) {  //查询最新的登录时间,为空说明时第一次登录
            map.put("first", "1");
        }
        //记录此次登录时间
        LambdaUpdateWrapper<Admin> lqw = new LambdaUpdateWrapper<>();
        lqw.eq(Admin::getAdminId, adminLoginUser.getAdmin().getAdminId())
                .set(Admin::getLastLoginTime, LocalDateTime.now());
        this.update(lqw);
        //使用userId生成token
        String userId = adminLoginUser.getAdmin().getAdminId().toString();
        String jwt = JwtUtil.createJWT(userId);
        //把完整的用户信息存入redis
        map.put("token", jwt);
        map.put("username", adminLoginUser.getUsername());
        redisTemplate.opsForValue().set("login_admin_" + userId, adminLoginUser, 600, TimeUnit.MINUTES);
        return ResultView.success(map);
    }

    //管理员退出登录
    public ResultView<String> loginOutByAdmin() {
        //获取SecurityContexHolder中的用户id
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        Long id = loginUser.getAdmin().getAdminId();
        //删除redis中的值
        redisTemplate.delete("login_admin_" + id);
        return ResultView.success("退出成功");
    }

    //查询管理员列表
    public ResultView<Page> selectAdminList(Integer page, Integer pageSize, String name) {
        Page<Admin> pageInfo = new Page<>(page, pageSize);
        LambdaQueryWrapper<Admin> lqw = new LambdaQueryWrapper<>();
        lqw.eq(name != null, Admin::getUserName, name);
        pageInfo.setRecords(this.list(lqw));
        return ResultView.success(pageInfo);
    }

    //新增管理员
    @Transactional(rollbackFor = Exception.class)
    public ResultView<String> addAdmin(Admin admin) {
        this.save(admin);
        return ResultView.success("新增管理员成功");
    }

    //查询管理员详情
    public ResultView<Admin> selectAdminDetail(Long adminId) {
        return ResultView.success(this.getById(adminId));
    }

    //查询管理员管理楼宇信息
    public ResultView<List<String>> selectAdminManageArea(Long adminId) {
        //查询楼宇id列表
        LambdaQueryWrapper<AdminBuilding> lqw = new LambdaQueryWrapper<>();
        lqw.eq(AdminBuilding::getAdminId, adminId);
        List<AdminBuilding> adminBuildingList = adminBuildingDao.selectList(lqw);
        //查询对应的区域id列表
        List<String> areaIdList = adminBuildingList.stream().map(item -> {
            LambdaQueryWrapper<Building> areaLqw = new LambdaQueryWrapper<>();
            areaLqw.eq(Building::getBuildingId, item.getBuildingId());
            Building building = buildingDao.selectOne(areaLqw);
            LambdaQueryWrapper<Area> areaLambdaQueryWrapper = new LambdaQueryWrapper<>();
            areaLambdaQueryWrapper.eq(Area::getAreaId, building.getAreaId());
            Area area = areaDao.selectOne(areaLambdaQueryWrapper);
            String result = area.getAreaName()+"-"+building.getBuildingName();
            return result;
        }).collect(Collectors.toList());
        return ResultView.success(areaIdList);
    }

    //为管理员分配管理楼宇
    @Transactional(rollbackFor = Exception.class)
    public ResultView<String> AdminSetZones(Long adminId) {
        return null;
    }
}
